import signal
import sys
import time
import threading
import os

# 添加项目根目录到路径
if __name__ == "__main__":
    # 直接运行时，添加父目录到路径
    current_dir = os.path.dirname(os.path.abspath(__file__))
    parent_dir = os.path.dirname(current_dir)
    if parent_dir not in sys.path:
        sys.path.insert(0, parent_dir)
    
    # 使用绝对导入
    from core.config import setup_logging
    from core.connection import ConnectionManager
    from core.media import MediaProcessor
    from core.message import MessageProcessor
    from core.input_handler import InputHandler
    from core.data_processor import DataProcessor
    from core.error_handler import ErrorHandler
    from core.recovery import recovery_manager, resource_manager, health_checker, with_recovery
else:
    # 作为模块导入时，使用相对导入
    from .config import setup_logging
    from .connection import ConnectionManager
    from .media import MediaProcessor
    from .message import MessageProcessor
    from .input_handler import InputHandler
    from .data_processor import DataProcessor
    from .error_handler import ErrorHandler
    from .recovery import recovery_manager, resource_manager, health_checker, with_recovery

class MainController:
    """主控制器 - 统一管理所有系统组件"""
    
    def __init__(self):
        self.logger = setup_logging('Main')
        self.running = False
        self.components = {}
        
        # 初始化组件
        self._init_components()
        
        # 设置恢复机制
        self._setup_recovery()
        
        # 设置健康检查
        self._setup_health_checks()
        
        # 设置信号处理
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)
    
    def _init_components(self):
        """初始化所有组件"""
        print("\n=== 系统初始化 ===")
        
        try:
            # 核心组件
            print("[1/6] 错误处理器...", end=" ")
            self.components['error_handler'] = ErrorHandler()
            print("✓ 成功")
            
            print("[2/6] 连接管理器...", end=" ")
            self.components['connection'] = ConnectionManager()
            print("✓ 成功")
            
            print("[3/6] 媒体处理器...", end=" ")
            self.components['media'] = MediaProcessor(self.components['connection'])
            print("✓ 成功")
            
            # 初始化媒体设备
            print("  └─ 摄像头初始化...", end=" ")
            if self.components['media'].init_camera():
                print("✓ 成功")
            else:
                print("✗ 失败: 摄像头设备不可用")
            
            print("  └─ 音频设备初始化...", end=" ")
            if self.components['media'].init_audio():
                print("✓ 成功")
            else:
                print("✗ 失败: 音频设备不可用")
            print("  └─ 超声波初始化...", end=" ")
            if self.components['media'].start_ultrasonic():
                print("✓ 成功")
            else:
                print("✗ 失败: 超声波不可用")
            
            print("[4/6] 数据处理器...", end=" ")
            self.components['data'] = DataProcessor()
            print("✓ 成功")
            
            print("[5/6] 消息处理器...", end=" ")
            self.components['message'] = MessageProcessor(
                self.components['connection'],
                self.components['media']
            )
            print("✓ 成功")
            
            print("[6/6] 输入处理器...", end=" ")
            self.components['input'] = InputHandler(
                self.components['message'],
                self.components['error_handler'],
                self.components['data']
            )
            print("✓ 成功")
            
            print("\n✓ 所有组件初始化完成\n")
            
        except Exception as e:
            print(f"✗ 失败: {e}")
            raise
    
    def _setup_recovery(self):
        """设置恢复机制"""
        try:
            # 注册组件恢复回调
            recovery_manager.register_recovery_callback('connection', self._recover_connection)
            recovery_manager.register_recovery_callback('media', self._recover_media)
            recovery_manager.register_recovery_callback('input', self._recover_input)
            
            # 注册资源清理
            resource_manager.register_resource('connection', self.components.get('connection'), 
                                             lambda x: x.close() if x else None)
            resource_manager.register_resource('media', self.components.get('media'),
                                             lambda x: x.cleanup() if x else None)
            resource_manager.register_resource('input', self.components.get('input'),
                                             lambda x: x.stop() if x else None)
            
        except Exception as e:
            self.logger.error(f"设置恢复机制失败: {e}")
    
    def _setup_health_checks(self):
        """设置健康检查"""
        try:
            # 注册健康检查
            health_checker.register_health_check('connection', 
                                                self._check_connection_health,
                                                self._recover_connection)
            health_checker.register_health_check('media',
                                                self._check_media_health,
                                                self._recover_media)
            health_checker.register_health_check('input',
                                                self._check_input_health,
                                                self._recover_input)
            
        except Exception as e:
            self.logger.error(f"设置健康检查失败: {e}")
    
    def _recover_connection(self):
        """恢复连接组件"""
        try:
            if 'connection' in self.components:
                self.components['connection'].close()
                time.sleep(2)
                # 重新连接
                if self.components['connection'].connect():
                    # 连接成功后进行身份认证
                    if self.components['connection'].authenticate():
                        self.logger.info("连接和身份认证恢复成功")
                        return True
                    else:
                        self.logger.error("连接恢复成功但身份认证失败")
                        return False
                else:
                    self.logger.error("连接恢复失败")
                    return False
            return False
        except Exception as e:
            self.logger.error(f"恢复连接失败: {e}")
            return False
    
    def _recover_media(self):
        """恢复媒体组件"""
        try:
            if 'media' in self.components:
                self.components['media'].cleanup()
                time.sleep(1)
                # 重新初始化摄像头和音频
                camera_ok = self.components['media'].init_camera()
                audio_ok = self.components['media'].init_audio()
                # 若摄像头重新可用，自动重启自动拍照与视频字节流
                if camera_ok:
                    try:
                        self.components['media'].start_auto_capture()
                    except Exception as e:
                        self.logger.warning(f"自动拍照重启失败: {e}")
                    try:
                        # 内部含握手逻辑，失败则不传输
                        self.components['media'].start_video_stream()
                    except Exception as e:
                        self.logger.warning(f"视频字节流重启失败: {e}")
                return camera_ok or audio_ok  # 至少一个成功即可
            return False
        except Exception as e:
            self.logger.error(f"恢复媒体失败: {e}")
            return False
    
    def _recover_input(self):
        """恢复输入组件"""
        try:
            if 'input' in self.components:
                self.components['input'].stop()
                time.sleep(1)
                self.components['input'].start()
                return True
            return False
        except Exception as e:
            self.logger.error(f"恢复输入失败: {e}")
            return False
    
    def _check_connection_health(self):
        """检查连接健康状态"""
        try:
            return self.components.get('connection', {}).is_connected() if 'connection' in self.components else False
        except:
            return False
    
    def _check_media_health(self):
        try:
            media = self.components.get('media')
            if not media:
                return False
            return hasattr(media, 'cap') and media.cap is not None
        except:
            return False
    
    def _check_input_health(self):
        """检查输入健康状态"""
        try:
            input_handler = self.components.get('input')
            if not input_handler:
                return False
            return getattr(input_handler, 'running', False)
        except:
            return False
    
    def start(self):
        """启动系统"""
        try:
            print("=== 系统启动 ===")
            self.running = True
            
            # 连接服务器
            print("[1/5] 连接服务器...", end=" ")
            if not self.components['connection'].connect():
                print("✗ 失败: 无法连接到服务器")
                raise Exception("无法连接到服务器")
            print("✓ 成功")
            
            # 身份认证
            print("[1.5/5] 身份认证...", end=" ")
            if not self.components['connection'].authenticate():
                print("✗ 失败: 身份认证失败")
                print("\n=== 连接诊断 ===")
                self.components['connection'].diagnose_connection()
                print("\n请检查以下可能的问题:")
                print("1. 服务器是否正常运行")
                print("2. 网络连接是否稳定")
                print("3. 服务器是否正确响应身份认证请求")
                print("4. 防火墙是否阻止了连接")
                raise Exception("身份认证失败")
            print("✓ 成功")
            
            # 启动输入监听
            print("[2/5] 启动输入监听...", end=" ")
            self.components['input'].start()
            print("✓ 成功")
            
            # 启动健康检查
            print("[3/5] 启动健康检查...", end=" ")
            health_checker.start()
            print("✓ 成功")
            
            # 获取初始数据
            print("[4/5] 获取位置数据...", end=" ")
            try:
                self.components['data'].generate_location_data()
                print("✓ 成功")
            except Exception as e:
                print(f"✗ 失败: {e}")
            
            print("[5/5] 获取摄像头数据...", end=" ")
            try:
                self.components['data'].generate_camera_data(self.components['media'])
                print("✓ 成功")
            except Exception as e:
                print(f"✗ 失败: {e}")

            print("[5.5/5] 并行握手与启动音频/视频...", end=" ")
            try:
                media = self.components['media']
                def start_audio():
                    try:
                        media.start_audio_stream()
                    except Exception:
                        pass
                def start_video():
                    try:
                        media.start_video_stream()
                    except Exception:
                        pass
                ta = threading.Thread(target=start_audio, daemon=True)
                tv = threading.Thread(target=start_video, daemon=True)
                ta.start(); tv.start()
                while True:
                    ok_a = bool(getattr(media, '_audio_handshake_done', False))
                    ok_v = bool(getattr(media, '_handshake_done', False))
                    if ok_a and ok_v:
                        print("✓ 成功")
                        break
                    if not getattr(media, 'audio_streaming', False):
                        try:
                            media.start_audio_stream()
                        except Exception:
                            pass
                    if not getattr(media, 'streaming', False):
                        try:
                            media.start_video_stream()
                        except Exception:
                            pass
                    time.sleep(0.5)
            except Exception as e:
                print(f"✗ 失败: {e}")
            
            # 启动自动拍照功能
            print("[6/6] 启动自动拍照...", end=" ")
            try:
                if self.components['media'].start_auto_capture():
                    print("✓ 成功")
                else:
                    print("✗ 失败: 摄像头不可用")
            except Exception as e:
                print(f"✗ 失败: {e}")

            print("\n✓ 系统启动完成\n")

            # 默认启动视频字节流传输（需身份确认后的握手成功）
            try:
                print("[7/7] 启动视频字节流...", end=" ")
                if self.components['media'].start_video_stream():
                    print("✓ 成功")
                else:
                    print("✗ 失败: 握手未成功或摄像头不可用")
            except Exception as e:
                print(f"✗ 失败: {e}")

            # 主循环
            self._main_loop()
            
        except Exception as e:
            print(f"\n✗ 系统启动失败: {e}")
            self.stop()
            raise
    
    def _main_loop(self):
        """主循环"""
        # 进入主循环
        
        try:
            while self.running:
                # 检查连接状态
                if not self.components['connection'].is_connected():
                    self.logger.warning("连接断开，尝试重连...")
                    if self.components['connection'].connect():
                        # 重连成功后进行身份认证
                        if not self.components['connection'].authenticate():
                            self.logger.error("重连成功但身份认证失败")
                            # 进行连接诊断
                            self.logger.info("开始连接诊断...")
                            self.components['connection'].diagnose_connection()
                            self.logger.error("等待5秒后重试")
                            time.sleep(5)
                            continue
                        self.logger.info("重连和身份认证成功")
                    else:
                        self.logger.error("重连失败")
                        # 进行连接诊断
                        self.logger.info("开始连接诊断...")
                        self.components['connection'].diagnose_connection()
                        self.logger.error("等待5秒后重试")
                        time.sleep(5)
                        continue
                
                # 处理接收到的消息
                try:
                    message = self.components['connection'].receive_and_confirm(timeout=1.0)
                    if message:
                        self.components['message'].process_message(message)
                except Exception as e:
                    if "timeout" not in str(e).lower():
                        self.logger.error(f"消息处理错误: {e}")
                
                # 短暂休眠
                time.sleep(0.1)
                
        except KeyboardInterrupt:
            self.logger.info("收到中断信号")
        except Exception as e:
            self.logger.error(f"主循环错误: {e}")
        finally:
            self.stop()
    
    def stop(self):
        """停止系统"""
        if not self.running:
            return
        
        self.logger.info("正在停止系统...")
        self.running = False
        
        try:
            # 停止健康检查
            health_checker.stop()
            
            # 停止各个组件
            if 'input' in self.components:
                self.components['input'].stop()
            
            if 'media' in self.components:
                # 停止自动拍照功能
                self.components['media'].stop_auto_capture()
                self.components['media'].cleanup()
            
            if 'connection' in self.components:
                self.components['connection'].close()
            
            # 清理所有资源
            resource_manager.cleanup_all()
            
            self.logger.info("系统已停止")
            
        except Exception as e:
            self.logger.error(f"停止系统时出错: {e}")
    
    def _signal_handler(self, signum, frame):
        """信号处理器"""
        self.logger.info(f"收到信号 {signum}，准备退出...")
        self.stop()
        sys.exit(0)
    
    def get_status(self):
        """获取系统状态"""
        status = {
            'running': self.running,
            'components': {}
        }
        
        try:
            # 连接状态
            status['components']['connection'] = {
                'connected': self.components['connection'].is_connected()
            }
            
            # 媒体状态
            status['components']['media'] = {
                'streaming': getattr(self.components['media'], 'streaming', False)
            }
            
            # 输入状态
            status['components']['input'] = {
                'running': getattr(self.components['input'], 'running', False)
            }
            
            # 错误状态
            status['components']['errors'] = {
                'summary': self.components['error_handler'].get_summary()
            }
            
            # 健康检查状态
            status['health'] = health_checker.get_status()
            
        except Exception as e:
            self.logger.error(f"获取状态失败: {e}")
        
        return status
    
    def restart_component(self, component_name):
        """重启指定组件"""
        try:
            if component_name in self.components:
                self.logger.info(f"重启组件: {component_name}")
                
                # 特殊处理某些组件
                if component_name == 'connection':
                    self.components['connection'].close()
                    time.sleep(1)
                    self.components['connection'].connect()
                elif component_name == 'input':
                    self.components['input'].stop()
                    time.sleep(1)
                    self.components['input'].start()
                
                self.logger.info(f"组件 {component_name} 重启完成")
                return True
            else:
                self.logger.error(f"未知组件: {component_name}")
                return False
                
        except Exception as e:
            self.logger.error(f"重启组件 {component_name} 失败: {e}")
            return False

def main():
    """主函数"""
    controller = MainController()
    
    try:
        controller.start()
    except KeyboardInterrupt:
        print("\n程序被用户中断")
    except Exception as e:
        print(f"程序异常退出: {e}")
    finally:
        controller.stop()

if __name__ == "__main__":
    main()